JS30 Day 14 筆記


Posted by GL on 2023-05-25

目標

介紹 JavaScript 賦值時何時為複製(Copy)以及引用(refrence)。

Demo

step 1 : 原始型別(Call by value)

原始型別(String、Number、Boolean、Null、undefined、NaN),複製時為 Call by value

let age = 100;
let age2 = age;
console.log(age, age2); // 100 100
age = 200;
console.log(age, age2); // 200 100

let name = 'Wes';
let name2 = name;
console.log(name, name2); // Wes Wes
name = 'wesley';
console.log(name, name2); // wesley Wes

step 2 : 物件型別(Call by refrence)-陣列複製

物件型別(object、array)複製時為 Call by reference

// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

// and we want to make a copy of it.
const team = players; // team 與 palyers 指向同個記憶體位置(陣列['Wes', 'Sarah', 'Ryan', 'Poppy']),

console.log(players, team);

// team[3] 由於與 palyers 指向同個記憶體位置,所以 team[3] ="Lux" 時,players[3] 也同樣改變
team[3] = 'Lux';  // ["Wes", "Sarah", "Ryan", "Lux"] ["Wes", "Sarah", "Ryan", "Lux"]


// 複製時爲了避免因爲因 call by reference 改變到原有的陣列,有以下幾種複製方法
// slice will return a new array
const team2 = players.slice();

// or create a new array and concat the old one in
const team3 = [].concat(players);

// or use the new ES6 Spread
const team4 = [...players];

team4[3] = 'heeee hawww';
console.log(team4);

// or use Array.from()
const team5 = Array.from(players);

step 3 : 物件型別(Call by refrence)- 物件複製

// with Objects
const person = {
  name: 'Wes Bos',
  age: 80
};

// and think we make a copy:
const captain = person;
captain.number = 99;  // person = { name: 'Wes Bos',age: 99};


const cap2 = Object.assign({}, person, { number: 99, age: 12 });
console.log(cap2);  // Object {name: "Wes Bos", age: 12, number: 99}

// We will hopefully soon see the object ...spread
const cap3 = {...person};

// Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.

const wes = {
  name: 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.developer'
  }
};

console.clear();
console.log(wes);

const dev = Object.assign({}, wes);

dev.age = 50;
dev.social.twitter = '@asdf111';

console.log('wes', wes); 
console.log('dev', dev); // wes 的 social 下的 twitter 的值為'@asdf111'

step 4 : JSON.parse(JSON.stringify())

當物件型別要複製到第二層時,先將陣列或物件變成 string 後在轉成 JSON 格式(需排除第二層有 function )

const dev2 = JSON.parse(JSON.stringify(wes));

參考資料:


#JS 30







Related Posts

JS30 Day 17 筆記

JS30 Day 17 筆記

What Type of Laser Engraving Machine Should be Used for Stainless Steel Engraving?

What Type of Laser Engraving Machine Should be Used for Stainless Steel Engraving?

使用 Vue Cli 來建置Vue專案

使用 Vue Cli 來建置Vue專案


Comments